/*
 *  rayTracer.cpp
 *  Ray Tracer
 *
 *  Created by Chirantan Ekbote on 10/8/10.
 *  Copyright 2010 Ohio State University. All rights reserved.
 *
 */

#include "../include/rayTracer.h"

void rt(object* shapes, light* lights, camera* cam, image* im, const param* p) {
	// Various counters
	int i, j, k, l, index;
	double t;
	
	if (p->useTextures) {
		// set the random seed
		srand((unsigned int) time(NULL));
		
		// Randomly pick a sphere to apply texture to
		int objTex = (int) ((rand() / RAND_MAX) * shapes[0].shape.len);
		while (shapes[objTex+1].type != SPHERE) {
			objTex = (int) ((rand() / RAND_MAX) * shapes[0].shape.len);
		}
		shapes[objTex+1].shape.sp.useTexture = 1;
	}
	
	// start casting rays
	ray r;
	rgb color, c;
	
	for (i = 0; i < im->x; i++) {
		for (j = 0; j < im->y; j++) {
			// Jitter camera position
			color = makeRGB(0.0f, 0.0f, 0.0f);
			for (k = 0; k < p->numCameras; k++) {
				c = makeRGB(0.0f, 0.0f, 0.0f);
				
				// Jitter caera position
				r.origin = vec3Jitter(cam->pos, cam->u, cam->v, cam->n, p->cameraJitter, 
									  p->cameraJitter);
				
				// Supersample pixel
				for (l = 0; l < p->numSuperSamples; l++) {
					// Jitter bottom left pixel position
					// Dir = (L + u*i*pw + v*j*ph) - eye
					r.direction = vec3Sub(vec3Add(vec3Add(vec3Jitter(cam->blpos, cam->u, cam->v, 
																	 cam->n, cam->pw, cam->ph), 
														  vec3Mul(cam->u, cam->pw * (float)i)), 
												  vec3Mul(cam->v, cam->ph * (float)j)),
										  r.origin);
					r.direction = vec3UnitVector(r.direction);
					
					// Cast the ray
					if (castRay(&r, shapes, &index, &t)) {
						c = rgbAdd(objectOnHit(&(shapes[index]), &r, rayPointAt(&r, t),
											   shapes, lights, 0, p), 
								   c);
					} else {
						c = rgbAdd(makeRGB(0.15f, 0.15f, 0.15f), c);
					}

					
				}
				color = rgbAdd(rgbScalarDiv(c, p->numSuperSamples), color);			
			}
			im->raster[i][j] = rgbScalarDiv(color, p->numCameras);
		}
	}
}
